package com.tanhua.manage.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mongodb.client.result.UpdateResult;
import com.tanhua.dubbo.server.pojo.Comment;
import com.tanhua.manage.mapper.UserInfoMapper01;
import com.tanhua.manage.pojo.Publish;
import com.tanhua.manage.pojo.PublishInfo;
import com.tanhua.manage.pojo.Total;
import com.tanhua.manage.pojo.UserInfo;
import com.tanhua.manage.vo.PageResultVo;
import com.tanhua.manage.vo.PublishInfoVo;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class PublishInfoService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private static final ObjectMapper MAPPER = new ObjectMapper();

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private UserInfoMapper01 userInfoMapper01;

    //动态审核通过
    public Boolean pass(String token, List<String> publishIds) {
        if (CollectionUtils.isEmpty(publishIds)) {
            return false;
        }

        for (String publishId : publishIds) {
            Query query = Query.query(Criteria.where("publishId").is(publishId));
            PublishInfo publishInfo = mongoTemplate.findOne(query, PublishInfo.class);
            if (publishInfo.getState() != 1 && publishInfo.getState() != 3) {
                return false;
            }
            Update update = new Update();
            update.set("state", 5);
            String redisKey = "publishVo:" + publishId;
            if (redisTemplate.hasKey(redisKey)) {
                redisTemplate.delete(redisKey);
            }
            mongoTemplate.updateFirst(query, update, PublishInfo.class);
        }
        return true;
    }

    //动态审核拒绝
    public Boolean reject(String token, List<String> publishIds) {
        if (CollectionUtils.isEmpty(publishIds)) {
            return false;
        }

        for (String publishId : publishIds) {
            Query query = Query.query(Criteria.where("publishId").is(publishId));
            PublishInfo publishInfo = mongoTemplate.findOne(query, PublishInfo.class);
            if (publishInfo.getState() != 1 && publishInfo.getState() != 3) {
                return false;
            }
            Update update = new Update();
            update.set("state", 4);
            String redisKey = "publishVo:" + publishId;
            if (redisTemplate.hasKey(redisKey)) {
                redisTemplate.delete(redisKey);
            }
            mongoTemplate.updateFirst(query, update, PublishInfo.class);
        }
        return true;
    }

    //动态审核撤销
    public Boolean revocation(String token, List<String> publishIds) {
        if (CollectionUtils.isEmpty(publishIds)) {
            return false;
        }

        for (String publishId : publishIds) {
            Query query = Query.query(Criteria.where("publishId").is(publishId));
            PublishInfo publishInfo = mongoTemplate.findOne(query, PublishInfo.class);
            if (publishInfo.getState() == 1 || publishInfo.getState() == 3) {
                return false;
            }
            Update update = new Update();
            update.set("state", 3);
            String redisKey = "publishVo:" + publishId;
            if (redisTemplate.hasKey(redisKey)) {
                redisTemplate.delete(redisKey);
            }
            mongoTemplate.updateFirst(query, update, PublishInfo.class);
        }
        return true;
    }

    //置顶
    public Boolean top(String publishId, String token) {
        if (StringUtils.isEmpty(publishId)) {
            return false;
        }

        Query query = Query.query(Criteria.where("publishId").is(publishId).and("topState").is(1));
        Update update = new Update();
        update.set("topState", 2);
        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, PublishInfo.class);
        String redisKey = "publishVo:" + publishId;
        if (redisTemplate.hasKey(redisKey)) {
            redisTemplate.delete(redisKey);
        }
        return updateResult.getModifiedCount() == 1;
    }

    //取消置顶
    public Boolean untop(String publishId, String token) {
        if (StringUtils.isEmpty(publishId)) {
            return false;
        }

        Query query = Query.query(Criteria.where("publishId").is(publishId).and("topState").is(2));
        Update update = new Update();
        update.set("topState", 1);
        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, PublishInfo.class);
        String redisKey = "publishVo:" + publishId;
        if (redisTemplate.hasKey(redisKey)) {
            redisTemplate.delete(redisKey);
        }
        return updateResult.getModifiedCount() == 1;
    }

    //查看动态详情
    public PublishInfoVo getPublishInfo(String publishId, String token) {
        if (StringUtils.isEmpty(publishId)) {
            return null;
        }

        PublishInfoVo publishInfoVo = this.getPublishVoById(publishId);
        return publishInfoVo;
    }

    //消息翻页
    public PageResultVo messages(Integer pageSize, Integer page, String sortProp, String sortOrder, String id, Long sd, Long ed, Long uid, Integer state) {
        //必须的参数没有传递,返回null
        if (StringUtils.isEmpty(sortProp) || StringUtils.isEmpty(sortOrder) || StringUtils.isEmpty(state)) {
            return null;
        }

        //查询publishInfo表所有的信息,得到List<PublishInfo>
        Query query = new Query();
        List<PublishInfo> publishInfos = mongoTemplate.find(query, PublishInfo.class);
        List<String> ids = new ArrayList<>();
        //收集List<PublishInfo>里面所有的publishId到 List<String> ids中
        for (PublishInfo publishInfo : publishInfos) {
            ids.add(publishInfo.getPublishId());
        }
        //循环ids,每一个publishId都调用getPublishVoById方法得到PublishInfoVo,然后把得到的PublishInfoVo保存到PublishInfoVo表中
        for (String publishId : ids) {
            PublishInfoVo publishInfoVo = this.getPublishVoById(publishId);
            PublishInfoVo save = mongoTemplate.save(publishInfoVo);
        }

        //getItem方法是构建特定的条件查询PublishInfoVo表,得到一个List<PublishInfoVo>
        List<PublishInfoVo> list = this.getItem(page, pageSize, sortOrder, sortProp, state, sd, ed, id, uid);

        //封装pageResultVo
        PageResultVo pageResultVo = new PageResultVo();
        pageResultVo.setPage(page);
        pageResultVo.setPages(this.getTotal().get(3).getValue() % pageSize == 0 ? this.getTotal().get(3).getValue() / pageSize : (this.getTotal().get(3).getValue() / pageSize) + 1);
        pageResultVo.setPageSize(pageSize);
        pageResultVo.setCounts(this.getTotal().get(3).getValue());
        pageResultVo.setItems(list);
        //调用getTotal方法,得到totals集合
        pageResultVo.setTotals(this.getTotal());
        //删除PublishInfoVo表
        Query query1 = new Query();
        mongoTemplate.remove(query1, PublishInfoVo.class);
        //返回pageResultVo
        return pageResultVo;
    }

    //根据条件封装item集合
    private List<PublishInfoVo> getItem(Integer page, Integer pageSize, String sortOrder, String sortProp, Integer state, Long sd, Long ed, String id, Long uid) {
        long sTime = 0l;
        long eTime = 0l;
        if(sd.toString().equals("-1")){
            sTime=0L;
        }
        if(ed.toString().equals("-1")){
            eTime=10000000000000L;
        }
        Query queryPublishInfoVo = Query.query(Criteria.where("state").is(state+"")
                .andOperator(Criteria.where("createDate").gt(sTime), Criteria.where("createDate").lt(eTime)));
        System.out.println(state+"************************");
        if (sortOrder.equals("descending")) {
            PageRequest pageRequest = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.desc(sortProp)));
            queryPublishInfoVo.with(pageRequest);
        } else if (sortOrder.equals("ascending")) {
            PageRequest pageRequest = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.asc(sortProp)));
            queryPublishInfoVo.with(pageRequest);
        } else {
            return null;
        }

        if (!StringUtils.isEmpty(id)) {
            queryPublishInfoVo.addCriteria(Criteria.where("id").is(id));
        }
        if (uid != null) {
            queryPublishInfoVo.addCriteria(Criteria.where("userId").is(uid));
        }
        System.out.println(queryPublishInfoVo.toString());
        List<PublishInfoVo> publishInfoVos = mongoTemplate.find(queryPublishInfoVo, PublishInfoVo.class);
        return publishInfoVos;
    }

    //得到total集合
    public List<Total> getTotal() {
        List<Total> list = new ArrayList<>();
        Total total1 = new Total();
        total1.setTitle("待审核");
        total1.setCode("3");
        Query query = Query.query(Criteria.where("state").is(3));
        long count = mongoTemplate.count(query, PublishInfo.class);
        total1.setValue((int) count);

        Total total2 = new Total();
        total2.setTitle("已驳回");
        total2.setCode("4");
        Query query2 = Query.query(Criteria.where("state").is(4));
        long count2 = mongoTemplate.count(query2, PublishInfo.class);
        total2.setValue((int) count2);

        Total total3 = new Total();
        total3.setTitle("已通过");
        total3.setCode("5");
        Query query3 = Query.query(Criteria.where("state").is(5));
        long count3 = mongoTemplate.count(query3, PublishInfo.class);
        total3.setValue((int) count3);

        Total total4 = new Total();
        total4.setTitle("全部");
        total4.setCode("all");
        Query query5 = new Query();
        long count4 = mongoTemplate.count(query5, PublishInfo.class);
        total4.setValue((int) count4);

        list.add(total1);
        list.add(total2);
        list.add(total3);
        list.add(total4);

        return list;
    }

    //通过publishId得到publishInfoVo
    public PublishInfoVo getPublishVoById(String publishId) {
        String redisKey = "publishVo:" + publishId;
        PublishInfoVo publishInfoVo = new PublishInfoVo();
        try {
            if (redisTemplate.hasKey(redisKey)) {
                String s = redisTemplate.opsForValue().get(redisKey);
                publishInfoVo = MAPPER.readValue(s, PublishInfoVo.class);
                return publishInfoVo;
            }

            Query queryPublishInfo = Query.query(Criteria.where("publishId").is(publishId));
            PublishInfo publishInfo = mongoTemplate.findOne(queryPublishInfo, PublishInfo.class);

            //封装动态喜欢数
            String publishLoveKey = "QUANZI_COMMENT_LOVE_" + publishId;
            if (redisTemplate.hasKey(publishLoveKey)) {
                publishInfoVo.setLoveCount(Integer.valueOf(redisTemplate.opsForValue().get(publishLoveKey)));
            } else {
                Criteria criteria = Criteria.where("publishId").is(new ObjectId(publishId)).and("commentType").is(3);
                Query query = Query.query(criteria);
                long count = mongoTemplate.count(query, Comment.class);
                redisTemplate.opsForValue().set(publishLoveKey, String.valueOf(count));
                publishInfoVo.setLoveCount((int) count);
            }

            //封装动态点赞数
            String publishLikeKey = "QUANZI_COMMENT_LIKE_" + publishId;
            if (redisTemplate.hasKey(publishLikeKey)) {
                publishInfoVo.setLikeCount(Integer.valueOf(redisTemplate.opsForValue().get(publishLikeKey).toString()));
            } else {
                Criteria criteria = Criteria.where("publishId").is(new ObjectId(publishId)).and("commentType").is(1);
                Query query = Query.query(criteria);
                long count = mongoTemplate.count(query, Comment.class);
                redisTemplate.opsForValue().set(publishLikeKey, String.valueOf(count));
                publishInfoVo.setLikeCount((int) count);
            }

            //封装动态评论数
            String publishCommentKey = "QUANZI_COMMENT_COMMENT_" + publishId;
            if (redisTemplate.hasKey(publishCommentKey)) {
                publishInfoVo.setCommentCount(Integer.valueOf(redisTemplate.opsForValue().get(publishCommentKey).toString()));
            } else {
                Criteria criteria = Criteria.where("publishId").is(new ObjectId(publishId)).and("commentType").is(2);
                Query query = Query.query(criteria);
                long count = mongoTemplate.count(query, Comment.class);
                redisTemplate.opsForValue().set(publishCommentKey, String.valueOf(count));
                publishInfoVo.setCommentCount((int) count);
            }

            //封装动态举报数
            String publishReportCountKey = "QUANZI_COMMENT_REPORT_" + publishId;
            if (redisTemplate.hasKey(publishReportCountKey)) {
                publishInfoVo.setReportCount(Integer.valueOf(redisTemplate.opsForValue().get(publishReportCountKey).toString()));
            } else {
                Criteria criteria = Criteria.where("publishId").is(new ObjectId(publishId)).and("commentType").is(4);
                Query query = Query.query(criteria);
                long count = mongoTemplate.count(query, Comment.class);
                redisTemplate.opsForValue().set(publishReportCountKey, String.valueOf(count));
                publishInfoVo.setReportCount((int) count);
            }

            //封装动态转发数
            String publishForwardingCountKey = "QUANZI_COMMENT_FORWARD_" + publishId;
            if (redisTemplate.hasKey(publishForwardingCountKey)) {
                publishInfoVo.setForwardingCount(Integer.valueOf(redisTemplate.opsForValue().get(publishForwardingCountKey).toString()));
            } else {
                Criteria criteria = Criteria.where("publishId").is(new ObjectId(publishId)).and("commentType").is(5);
                Query query = Query.query(criteria);
                long count = mongoTemplate.count(query, Comment.class);
                redisTemplate.opsForValue().set(publishForwardingCountKey, String.valueOf(count));
                publishInfoVo.setForwardingCount((int) count);
            }

            //封装userId text Medias  CreateDate
            Query query = Query.query(Criteria.where("id").is(new ObjectId(publishId)));
            Publish publish = mongoTemplate.findOne(query, Publish.class);
            publishInfoVo.setText(publish.getText());
            publishInfoVo.setCreateDate(publish.getCreated());
            String[] objects = publish.getMedias().toArray(new String[publish.getMedias().size()]);
            publishInfoVo.setMedias(objects);
            publishInfoVo.setUserId(Integer.valueOf(publish.getUserId().toString()));

            //封装userLogo nickName
            QueryWrapper<UserInfo> queryWrapper2 = new QueryWrapper<>();
            queryWrapper2.eq("user_id", publish.getUserId());
            UserInfo userInfo = userInfoMapper01.selectOne(queryWrapper2);
            publishInfoVo.setNickname(userInfo.getNickName());
            publishInfoVo.setUserLogo(userInfo.getLogo());

            //封装与publishInfo相同的属性
            publishInfoVo.setId(publishId);
            publishInfoVo.setTopState(publishInfo.getTopState());
            publishInfoVo.setState(publishInfo.getState()+"");

            //存入Redis中
            String publishInfoVoToString = MAPPER.writeValueAsString(publishInfoVo);
            redisTemplate.opsForValue().set(redisKey, publishInfoVoToString);
            //返回
            return publishInfoVo;

        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
